﻿using System;
using System.IO;
using System.Linq;
using Microsoft.Office.Interop.Excel;
using NUnit.Framework;

namespace ExcelAutomator.Tests
{
	public class ExcelTestFixtureBase
	{
		#region Application

		private Application m_Application;
		private Application Application
		{
			get
			{
				if (m_Application == null)
				{
					m_Application = new Application();
					m_Application.DisplayAlerts = false;
					m_Application.EnableEvents = false;
				}
				return m_Application;
			}
		}

		#endregion

		protected const string SourceWbName = "Book_source.xlsx";
		protected const string SourceWbName2 = "Book_source_2.xlsx";
		protected const string SourceWbMacroName = "Book_macro.xlsm";
		protected const string SourceWbCopyName = "Book_source_copy.xlsx";
		protected const string TargetWbName = "Book_target.xlsx";
		protected readonly string EmptyInputFolderPath = Path.Combine(Environment.CurrentDirectory, "EmptyInputFolder");
		protected readonly string InputFolderPath = Path.Combine(Environment.CurrentDirectory, "Input");
		protected readonly string TargetFolderPath = Path.Combine(Environment.CurrentDirectory, "Target");
		protected readonly string OutputFolderPath = Path.Combine(Environment.CurrentDirectory, "Output");


		#region Setup/Teardown

		[TestFixtureSetUp]
		public void TestFixtureSetup()
		{
			TestHelper.ExtractResourceFromAssembly(Resource1.Book_source, SourceWbName, "Input");
			TestHelper.ExtractResourceFromAssembly(Resource1.Book_source_2, SourceWbName2, "Input");
			TestHelper.ExtractResourceFromAssembly(Resource1.Book_macro, SourceWbMacroName, InputFolderPath);
			TestHelper.ExtractResourceFromAssembly(Resource1.Book_target, TargetWbName, "Target");
			
		}

		[TestFixtureTearDown]
		public void TestFixtureTeardown()
		{
			if (m_Application != null)
			{
				m_Application.Quit();
			}


			if (Directory.Exists(EmptyInputFolderPath))
			{
				Directory.Delete(EmptyInputFolderPath, true);
			}

			if (Directory.Exists(InputFolderPath))
			{
				DeleteDirectory(InputFolderPath);
			}

			if (Directory.Exists(TargetFolderPath))
			{
				DeleteDirectory(TargetFolderPath);
			}
			if (Directory.Exists(OutputFolderPath))
			{
				DeleteDirectory(OutputFolderPath);
			}
		}

		[SetUp]
		public void Setup()
		{
		}

		[TearDown]
		public void Teardown()
		{
		}

		#endregion

		protected Application StartExcel()
		{
			return Application;
		}

		protected void QuitExcel()
		{
			Application.Quit();
		}

		#region ResolveRangeValues

		//private void ResolveRangeValues(ExcelAutomatorConfiguration cfg, Action<string> validationCallback)
		//{
		//  var operationCfg = cfg.Operations.First();
		//  var rngCfg = operationCfg.RangeConfigurations.First();

		//  ResolveRangeValues(operationCfg.TargetWorksheet, rngCfg.TargetAddress, validationCallback);
		//}

		protected void ResolveRangeValues(string workbook, string worksheet, string address, Action<string> validationCallback)
		{
			var wb = Application.OpenWorkbook(Path.Combine(Environment.CurrentDirectory, workbook));
			var ws = wb.Sheets.OfType<Worksheet>().Where(x => worksheet.Equals(x.Name)).SingleOrDefault();
			
			foreach (var valueToValidate in ws.get_Range(address, Type.Missing).Values<string>())
			{
				validationCallback(valueToValidate);
			}
		}

		private static void DeleteDirectory(string target_dir)
		{
			string[] files = Directory.GetFiles(target_dir);
			string[] dirs = Directory.GetDirectories(target_dir);

			foreach (string file in files)
			{
				File.SetAttributes(file, FileAttributes.Normal);
				File.Delete(file);
			}

			foreach (string dir in dirs)
			{
				DeleteDirectory(dir);
			}

			Directory.Delete(target_dir, false);
		}


		#endregion
	}
}
